using System;
using System.Collections.Generic;
using System.Drawing;
using System.Net;
using System.Text;

namespace YouTubeDupe
{
    /// <summary>
    /// A class which represenets a YouTube video.
    /// </summary>
    public class Video
    {
        string _id;
        string _title;
        string _author;
        string _url;
        string _length;
        string _description;
        string _tags;
        string _viewCount;
        string _thumbnailUrl;
        Bitmap _thumbnail = null;

        /// <summary>
        /// Instantiates a new instance of the video class.
        /// </summary>
        /// <param name="id">The id of the video.</param>
        /// <param name="title">The title of the video.</param>
        /// <param name="author">The author of the video.</param>
        /// <param name="url">The url of the video.</param>
        /// <param name="length">The length of the video.</param>
        /// <param name="description">The description of the video.</param>
        /// <param name="tags">The tags of the video.</param>
        /// <param name="viewCount">The viewCountof the video.</param>
        /// <param name="thumbnailUrl">The thumbnailUrl of the video.</param>
        public Video(string id, string title, string author, string url, string length,
            string description, string tags, string viewCount, string thumbnailUrl)
        {
            _id = id;
            _title = title;
            _author = author;
            _url = url;
            _length = length;
            _description = description;
            _tags = tags;
            _viewCount = viewCount;
            _thumbnailUrl = thumbnailUrl;

            // Download the thumnail, if this fails throw an exception.
            WebRequest request = WebRequest.Create(_thumbnailUrl);
            request.Timeout = 5000;
            HttpWebResponse response = request.GetResponse() as HttpWebResponse;
            if (response.StatusCode != HttpStatusCode.OK)
            {
                throw new WebException("Invalid response when downloading thumbnail.");
            }
            using (System.IO.Stream stream = response.GetResponseStream())
            {
                _thumbnail = new Bitmap(stream);
                stream.Close();
            }
        }

        /// <summary>
        /// Gets the ID of the video.
        /// </summary>
        public string ID
        {
            get { return _id; }
        }

        /// <summary>
        /// Gets the title of the video.
        /// </summary>
        public string Title
        {
            get { return _title; }
        }

        /// <summary>
        /// Gets the author of the video.
        /// </summary>
        public string Author
        {
            get { return _author; }
        }

        /// <summary>
        /// Gets the url of the video.
        /// </summary>
        public string URL
        {
            get { return _url; }
        }

        /// <summary>
        /// Gets the length of the video.
        /// </summary>
        public string Length
        {
            get { return _length; }
        }

        /// <summary>
        /// Gets the description of the video.
        /// </summary>
        public string Description
        {
            get { return _description; }
        }

        /// <summary>
        /// Gets the tags of the video.
        /// </summary>
        public string Tags
        {
            get { return _tags; }
        }

        /// <summary>
        /// Gets the view count of the video.
        /// </summary>
        public string ViewCount
        {
            get { return _viewCount; }
        }

        /// <summary>
        /// Gets the thumbnail url of the video.
        /// </summary>
        public string ThumbnailURL
        {
            get { return _thumbnailUrl; }
        }

        /// <summary>
        /// Gets the thumbnail of the video.
        /// </summary>
        public Bitmap Thumbnail
        {
            get { return _thumbnail; }
            set { _thumbnail = value; }
        }

        /// <summary>
        /// Compares a video with another video.
        /// </summary>
        /// <param name="video">The video to compare to.</param>
        /// <param name="tolerance">The tolerance of the comparison.</param>
        /// <returns>True if the videos are deemed the same; false otherwise.</returns>
        public bool Equals(Video video, int tolerance)
        {
            if (tolerance < 0 || tolerance > 100)
            {
                throw new Exception("Tolerance must be a value between 0 and 100.");
            }

            // Resize video if necessary.
            if (!this.Thumbnail.Size.Equals(video.Thumbnail.Size))
            {
                video.Thumbnail = new Bitmap(video.Thumbnail.GetThumbnailImage(this.Thumbnail.Width, this.Thumbnail.Height, new Image.GetThumbnailImageAbort(placeHolder), IntPtr.Zero));
            }

            // Create the rectangles to compare.
            Rectangle rectOne = new Rectangle(15, 25, 30, 15);
            Rectangle rectTwo = new Rectangle(45, 25, 30, 15);
            Rectangle rectThree = new Rectangle(15, 50, 30, 15);
            Rectangle rectFour = new Rectangle(45, 50, 30, 15);

            List<Rectangle> rectangles = new List<Rectangle>();
            rectangles.AddRange(new Rectangle[] { rectOne, rectTwo, rectThree, rectFour });

            int totalSquareDiff = 0;

            // Compares each pixel on all of the squares. If a certain amount of pixels
            // differ then that square is deemed different. If a certain amount of squares
            // differ then the video is deemed different. They are deemed equal otherwise.
            foreach (Rectangle rectangle in rectangles)
            {
                int totalPixelDiff = 0;
                for (int i = rectangle.Top; i < rectangle.Bottom; i++)
                {
                    for (int j = rectangle.Left; j < rectangle.Right; j++)
                    {
                        Color pixelOne = this.Thumbnail.GetPixel(j, i);
                        Color pixelTwo = video.Thumbnail.GetPixel(j, i);

                        int diffR = (int)Math.Abs(pixelOne.R - pixelTwo.R);
                        int diffG = (int)Math.Abs(pixelOne.G - pixelTwo.G);
                        int diffB = (int)Math.Abs(pixelOne.B - pixelTwo.B);

                        if ((diffR + diffG + diffB) > (tolerance * 3) / 2)
                        {
                            totalPixelDiff++;

                            if (totalPixelDiff >= 225)
                            {
                                totalSquareDiff++;

                                if (totalSquareDiff > 2)
                                {
                                    return false;
                                }
                            }
                        }
                    }
                }
            }

            return true;
        }

        /// <summary>
        /// Function needed for the image resize method.
        /// </summary>
        /// <returns>False regardless.</returns>
        private static bool placeHolder() { return false; }
    }
}
